
#ifndef __LIBERTY_ENGINE_ICOMPONENTFACTORY_H__
#define __LIBERTY_ENGINE_ICOMPONENTFACTORY_H__

#include <Liberty3D/Liberty3D.h>

namespace Liberty { namespace Engine {
    class IComponentFactory {
    public:
        virtual ~IComponentFactory() {}

    public:
        virtual std::shared_ptr<Component> create(const char* name) = 0;
    };

    class ComponentFactory {
    public:
        static void registerFactory(IComponentFactory*);

        static std::shared_ptr<Component> create(const char* name);
    };

    template <typename T> class ComponentFactoryImpl : public IComponentFactory {
    private:
        const char* _name;

    public:
        ComponentFactoryImpl(const char* n) : _name(n) {
            ComponentFactory::registerFactory(this);
        }

        virtual std::shared_ptr<Component> create(const char* name) {
            if (strcmp(_name, name) == 0) {
                return std::shared_ptr<Component>(new T());
            }

            return std::shared_ptr<Component>();
        }
    };

#define LIBERTY_DEFINE_COMPONENT(name)              static ComponentFactoryImpl<name>      ComponentFactory_##name(#name);
#define LIBERTY_DEFINE_COMPONENT_2(name, className) static ComponentFactoryImpl<className> ComponentFactory_##name(#name);
}}

#endif
